package velox.jcr.mapper;

import org.apache.commons.collections.map.LRUMap;


public class SimpleSecondLevelCache implements SecondLevelCache, SecondLevelCacheStatistics {
	private LRUMap entityCache;
	private LRUMap auxCache;
	
	private int auxHitCount = 0;
	private int entityHitCount = 0;
	private int auxMissCount = 0;
	private int entityMissCount = 0;
	
	public SimpleSecondLevelCache(int maxSize) {
		entityCache = new LRUMap(maxSize);
		auxCache = new LRUMap(maxSize);
	}

	public synchronized Object get(String key, CacheType cacheType) {
		if (cacheType == CacheType.ENTITY) {
			Object o = entityCache.get(key);
			if (o == null) entityHitCount++;
			else entityMissCount++;
			return o;
		} else {
			Object o = auxCache.get(key);
			if (o == null) auxHitCount++;
			else auxMissCount++;
			return o;
		}
	}

	public synchronized void put(String key, Object obj, CacheType cacheType) {
		if (cacheType == CacheType.ENTITY) {
			entityCache.put(key, obj);
		} else {
			auxCache.put(key, obj);
		}
	}

	public synchronized void invalidateAux() {
		auxCache.clear();
	}

	public synchronized void invalidateEntity(String key) {
		entityCache.remove(key);
	}

	public synchronized void invalidateAll() {
		auxCache.clear();
		entityCache.clear();
	}

	public int getCapacity(CacheType cacheType) {
		if (cacheType == CacheType.AUX) return auxCache.maxSize();
		return entityCache.maxSize();
	}

	public int getHits(CacheType cacheType) {
		if (cacheType == CacheType.AUX) return auxHitCount;
		return entityHitCount;
	}

	public int getMisses(CacheType cacheType) {
		if (cacheType == CacheType.AUX) return auxMissCount;
		return entityMissCount;
	}

	public int getSize(CacheType cacheType) {
		if (cacheType == CacheType.AUX) return auxCache.size();
		return entityCache.size();
	}

	public void resetStatistics() {
		auxHitCount = entityHitCount = auxMissCount = entityMissCount = 0;
	}
}
